From 4fca2a798152dccd59ccd5ffb12a5d3c596d9656 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Sun, 18 Feb 2007 15:29:40 +0000 Subject: [PATCH] hvm: Support PUSH from mmio area (opcode 0xFF/6). Also fix a bogus assertion in vlapic device model. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/io.c | 5 +++++ xen/arch/x86/hvm/platform.c | 20 ++++++++++++++++++++ xen/arch/x86/hvm/vlapic.c | 2 +- xen/include/asm-x86/hvm/io.h | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c index 4637515bf4..8d369b3b49 100644 --- a/xen/arch/x86/hvm/io.c +++ b/xen/arch/x86/hvm/io.c @@ -686,6 +686,11 @@ static void hvm_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p, set_reg_value(size, index, 0, regs, p->data); } break; + + case INSTR_PUSH: + mmio_opp->addr += hvm_get_segment_base(current, x86_seg_ss); + hvm_copy_to_guest_virt(mmio_opp->addr, &p->data, size); + break; } } diff --git a/xen/arch/x86/hvm/platform.c b/xen/arch/x86/hvm/platform.c index 32246da991..9ed0cd2508 100644 --- a/xen/arch/x86/hvm/platform.c +++ b/xen/arch/x86/hvm/platform.c @@ -716,6 +716,11 @@ static int mmio_decode(int address_bytes, unsigned char *opcode, mmio_op->instr = INSTR_SUB; return DECODE_success; + case 6: /* push */ + mmio_op->instr = INSTR_PUSH; + mmio_op->operand[0] = mmio_op->operand[1]; + return DECODE_success; + default: printk("%x/%x, This opcode isn't handled yet!\n", *opcode, ins_subtype); @@ -1131,6 +1136,21 @@ void handle_mmio(unsigned long gpa) mmio_operands(IOREQ_TYPE_XOR, gpa, mmio_op, op_size); break; + case INSTR_PUSH: + if ( ad_size == WORD ) + { + mmio_op->addr = (uint16_t)(regs->esp - op_size); + regs->esp = mmio_op->addr | (regs->esp & ~0xffff); + } + else + { + regs->esp -= op_size; + mmio_op->addr = regs->esp; + } + /* send the request and wait for the value */ + send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, op_size, 0, IOREQ_READ, df, 0); + break; + case INSTR_CMP: /* Pass through */ case INSTR_TEST: case INSTR_SUB: diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 450dcb3237..2cc294ba36 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -459,7 +459,7 @@ static void vlapic_set_tdcr(struct vlapic *vlapic, unsigned int val) static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset, unsigned int len, unsigned int *result) { - ASSERT((len == 4) && (offset > 0) && (offset <= APIC_TDCR)); + ASSERT((len == 4) && (offset >= 0) && (offset <= APIC_TDCR)); switch ( offset ) { diff --git a/xen/include/asm-x86/hvm/io.h b/xen/include/asm-x86/hvm/io.h index c71a9bbc6c..b08cc781cb 100644 --- a/xen/include/asm-x86/hvm/io.h +++ b/xen/include/asm-x86/hvm/io.h @@ -65,6 +65,7 @@ #define INSTR_XCHG 14 #define INSTR_SUB 15 #define INSTR_ADD 16 +#define INSTR_PUSH 17 #define MAX_INST_LEN 15 /* Maximum instruction length = 15 bytes */ -- 2.30.2